#include "list.h"
#include "stdlib.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void lcreate(DoublyLinkedListObjct *obj);
static void lpush_back(DoublyLinkedListObjct *obj, void *data);
static void lpush_front(DoublyLinkedListObjct *obj, void *data);
static void *lpop_back(DoublyLinkedListObjct *obj);
static void *lpop_front(DoublyLinkedListObjct *obj);
static void *lget(DoublyLinkedListObjct *obj, int index);
static void linsert(DoublyLinkedListObjct *obj, int index, void *data);
static void lremove(DoublyLinkedListObjct *obj, int index);
static void lclear(DoublyLinkedListObjct *obj);
static int llength(DoublyLinkedListObjct *obj);
static void *lmalloc(void *data, int size);

/**
 * @brief 创建并初始化一个双向链表对象。
 *
 * 该函数用于创建并初始化一个双向链表对象，包括设置头指针、尾指针和初始化锁。
 * 
 * @param obj 指向要初始化的双向链表对象的指针。
 */
void createDoublyLinkedListObjct(DoublyLinkedListObjct *obj)
{
    // 接口初始化
    // obj->create = lcreate;
    obj->push_back = lpush_back;
    obj->push_front = lpush_front;
    obj->pop_back = lpop_back;
    obj->pop_front = lpop_front;
    obj->get = lget;
    obj->insert = linsert;
    obj->remove = lremove;
    obj->clear = lclear;
    obj->length = llength;
    obj->lmalloc = lmalloc;

    // 创建双向链表
    // obj->create(obj);
    lcreate(obj);
}

// create 创建双向链表
void lcreate(DoublyLinkedListObjct *obj)
{
    _DoublyLinkedList *list = NULL;
    list = (_DoublyLinkedList *)malloc(sizeof(_DoublyLinkedList));

    if (list == NULL)
    {
        while (1)
            ; // printf("Error: Memory allocation failed\n");
    }

    // 创建头节点
    list->head = (_Node *)malloc(sizeof(_Node));
    if (list->head == NULL)
    {
        while (1)
            ; // printf("Error: Memory allocation failed\n");
    }
    list->head->data = NULL;
    list->head->next = NULL;
    list->head->prev = NULL;

    // 创建尾节点
    list->tail = (_Node *)malloc(sizeof(_Node));
    if (list->tail == NULL)
    {
        while (1)
            ; // printf("Error: Memory allocation failed\n");
    }
    list->tail->data = NULL;
    list->tail->next = NULL;
    list->tail->prev = NULL;

    // 初始化头尾节点
    list->head->next = list->tail;
    list->tail->prev = list->head;
    list->length = 0;

    obj->list = *list;
}

// push_back 在链表尾部插入元素
void lpush_back(DoublyLinkedListObjct *obj, void *data)
{
    _DoublyLinkedList *list = &(obj->list);
    // 创建新节点
    _Node *new_node = (_Node *)malloc(sizeof(_Node));
    if (new_node == NULL)
    {
        while (1)
            ; // printf("Error: Memory allocation failed\n");
    }
    new_node->data = data;
    new_node->next = NULL;
    new_node->prev = NULL;

    // 将新节点插入到链表尾部
    new_node->prev = list->tail->prev;
    new_node->next = list->tail;
    list->tail->prev->next = new_node;
    list->tail->prev = new_node;

    // 更新链表长度
    list->length++;
}

// push_front 在链表头部插入元素
void lpush_front(DoublyLinkedListObjct *obj, void *data)
{
    _DoublyLinkedList *list = &(obj->list);
    // 创建新节点
    _Node *new_node = (_Node *)malloc(sizeof(_Node));
    if (new_node == NULL)
    {
        while (1)
            ; // printf("Error: Memory allocation failed\n");
    }
    new_node->data = data;
    new_node->next = NULL;
    new_node->prev = NULL;

    // 将新节点插入到链表头部
    new_node->prev = list->head;
    new_node->next = list->head->next;
    list->head->next->prev = new_node;
    list->head->next = new_node;

    // 更新链表长度
    list->length++;
}


// 通用的 pop 函数
// void *lpop(DoublyLinkedListObjct *obj, int from_end) {
//     _DoublyLinkedList *list = &(obj->list);
//     if (list->length == 0) {
//         return NULL;
//     }

//     _Node *node_to_remove;
//     void *data;

//     if (from_end) {
//         // 从尾部删除
//         node_to_remove = list->tail->prev;
//         list->tail->prev = node_to_remove->prev;
//         list->tail->prev->next = list->tail;
//     } else {
//         // 从头部删除
//         node_to_remove = list->head->next;
//         list->head->next = node_to_remove->next;
//         list->head->next->prev = list->head;
//     }

//     // 获取被删除节点的数据
//     data = node_to_remove->data;

//     // 释放被删除节点
//     free(node_to_remove);

//     // 更新链表长度
//     list->length--;

//     return data;
// }

// pop_back 删除链表尾部元素,返回被删除的元素, 整合
// void *lpop_back(DoublyLinkedListObjct *obj)
// {
//     return lpop(obj, 1);
// }

// pop_front 删除链表头部元素,返回被删除的元素, 整合
// void *lpop_front(DoublyLinkedListObjct *obj)
// {
//     return lpop(obj, 0);
// }

// pop_back 删除链表尾部元素,返回被删除的元素
void *lpop_back(DoublyLinkedListObjct *obj)
{
    _DoublyLinkedList *list = &(obj->list);
    if (list->length == 0)
    {
        return NULL;
    }

    // 获取尾部节点
    _Node *tail_node = list->tail->prev;

    // 更新链表尾部
    list->tail->prev = tail_node->prev;
    list->tail->prev->next = list->tail;

    // 返回被删除的元素
    void *data = tail_node->data;

    // 释放内存

    free(tail_node);

    // 更新链表长度
    list->length--;

    return data;
}

// pop_front 删除链表头部元素,返回被删除的元素
void *lpop_front(DoublyLinkedListObjct *obj)
{
    _DoublyLinkedList *list = &(obj->list);
    if (list->length == 0)
    {
        return NULL;
    }

    // 获取头部节点
    _Node *head_node = list->head->next;
    // 更新链表头部
    list->head->next = head_node->next;
    list->head->next->prev = list->head;

    // 返回被删除的元素
    void *data = head_node->data;

    // 释放内存
    free(head_node);

    // 更新链表长度
    list->length--;

    return data;
}

// get 获取指定位置的元素
void *lget(DoublyLinkedListObjct *obj, int index)
{
    _DoublyLinkedList *list = &(obj->list);
    if (index < 0 || index >= list->length)
    {
        return NULL;
    }

    // 获取指定位置的节点
    _Node *current_node = list->head->next;
    for (int i = 0; i < index; i++)
    {
        current_node = current_node->next;
    }

    // 返回指定位置的元素
    return current_node->data;
}

// insert 在指定位置插入元素
void linsert(DoublyLinkedListObjct *obj, int index, void *data)
{
    _DoublyLinkedList *list = &(obj->list);
    if (index < 0 || index > list->length)
    {
        // index不合法，插入失败，释放data的内存
        free(data);
        return;
    }

    // 创建新节点
    _Node *new_node = (_Node *)malloc(sizeof(_Node));
    if (new_node == NULL)
    {
        while (1)
            ; // printf("Error: Memory allocation failed\n");
    }
    new_node->data = data;
    new_node->next = NULL;
    new_node->prev = NULL;

    // 在指定位置插入新节点
    _Node *current_node = list->head->next;
    for (int i = 0; i < index; i++)
    {
        current_node = current_node->next;
    }
    new_node->prev = current_node->prev;
    new_node->next = current_node;
    current_node->prev->next = new_node;
    current_node->prev = new_node;

    // 更新链表长度
    list->length++;
}

// remove 删除指定位置的元素
void lremove(DoublyLinkedListObjct *obj, int index)
{
    _DoublyLinkedList *list = &(obj->list);
    if (index < 0 || index >= list->length)
    {
        return;
    }

    // 获取指定位置的节点
    _Node *current_node = list->head->next;
    for (int i = 0; i < index; i++)
    {
        current_node = current_node->next;
    }

    // 更新链表
    current_node->prev->next = current_node->next;
    current_node->next->prev = current_node->prev;

    // 释放内存
    free(current_node->data);
    free(current_node);

    // 更新链表长度
    list->length--;
}

// clear 清空链表
void lclear(DoublyLinkedListObjct *obj)
{
    _DoublyLinkedList *list = &(obj->list);
    while (list->length > 0)
    {
        // obj->pop_back(obj);
        obj->remove(obj,0);
    }
}

// length 获取链表长度
int llength(DoublyLinkedListObjct *obj)
{
    return (obj->list).length;
}

// 将数据转换成void*并创建内存空间
void *lmalloc(void *data, int size)
{
    void *new_data = malloc(size);
    memcpy(new_data, data, size);
    return new_data;
}
